package com.csun.cmny.provider.service.impl;

import com.csun.cmny.base.dto.LoginAuthDto;
import com.csun.cmny.base.enums.ErrorCodeEnum;
import com.csun.cmny.core.support.BaseService;
import com.csun.cmny.provider.dao.DmcPointCardBindMapper;
import com.csun.cmny.provider.exceptions.DmcBizException;
import com.csun.cmny.provider.exceptions.OmcBizException;
import com.csun.cmny.provider.model.constant.CardConstant;
import com.csun.cmny.provider.model.constant.DeviceConstant;
import com.csun.cmny.provider.model.domain.DmcPointCardBind;
import com.csun.cmny.provider.model.dto.PointCardAccountDto;
import com.csun.cmny.provider.model.dto.PointCardAccountQueryDto;
import com.csun.cmny.provider.model.dto.card.PointCardBindDto;
import com.csun.cmny.provider.model.dto.card.PointCardBindQueryDto;
import com.csun.cmny.provider.model.dto.rfid.BindDmcRfidLabelOldmanDto;
import com.csun.cmny.provider.model.dto.rfid.RfidLabelPageQuery;
import com.csun.cmny.provider.model.vo.OldmanBedRoomBuildingVo;
import com.csun.cmny.provider.model.vo.OpcUserVo;
import com.csun.cmny.provider.model.vo.PointCardAccountVO;
import com.csun.cmny.provider.model.vo.card.PointCardBindVO;
import com.csun.cmny.provider.model.vo.rfid.DmcRfidLabelVo;
import com.csun.cmny.provider.service.DmcPointCardBindService;
import com.csun.cmny.provider.service.DmcRfidLabelOldmanService;
import com.csun.cmny.provider.service.OmcRpcService;
import com.csun.cmny.provider.service.UacRpcService;
import com.csun.cmny.util.PubUtils;
import com.csun.cmny.util.PublicUtil;
import com.csun.cmny.util.RedisKeyUtil;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
@Transactional
public class DmcPointCardBindServiceImpl extends BaseService<DmcPointCardBind> implements DmcPointCardBindService {

    @Resource
    private DmcPointCardBindMapper dmcPointCardBindMapper;
    @Resource
    private OmcRpcService omcRpcService;
    @Resource
    private DmcRfidLabelOldmanService dmcRfidLabelOldmanService;
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private UacRpcService uacRpcService;

    @Override
    public int bind(PointCardBindDto pointCardBindDto, LoginAuthDto loginAuthDto) {

        //绑定
        BindDmcRfidLabelOldmanDto bindDmcRfidLabelOldmanDto = new BindDmcRfidLabelOldmanDto();
        bindDmcRfidLabelOldmanDto.setOldmanName(pointCardBindDto.getOldmanName());
        bindDmcRfidLabelOldmanDto.setDeviceId(pointCardBindDto.getDeviceId());
        bindDmcRfidLabelOldmanDto.setOldmanId(pointCardBindDto.getHumanId());
        bindDmcRfidLabelOldmanDto.setRoleId(pointCardBindDto.getRoleId());

        Integer result = dmcRfidLabelOldmanService.bindDmcRfidLabelOldman(bindDmcRfidLabelOldmanDto);

//        Long deviceId = pointCardBindDto.getDeviceId();

//        DmcDevice dmcDevice = dmcDeviceService.selectByKey(deviceId);
//        if (!dmcDevice.getDeviceType().equals(DeviceConstant.RFID_LABEL)) {
//            throw new DmcBizException(ErrorCodeEnum.DMC100617007);
//        }
//
//        DmcPointCardBind bind = dmcPointCardBindMapper.selectByPrimaryKey(deviceId);
//        if (PublicUtil.isNotEmpty(bind)) {
//            throw new DmcBizException(ErrorCodeEnum.DMC100617001);
//        }

//        bind = new DmcPointCardBind();
//        BeanUtils.copyProperties(pointCardBindDto, bind);
//        bind.setStatus(CardConstant.INUSE_CARD_STATUS);

        //创建一卡通账户
        int i = omcRpcService.addPointCardAccount(new PointCardAccountDto(pointCardBindDto.getDeviceId(), loginAuthDto));
        if (i < 1) {
            throw new OmcBizException(ErrorCodeEnum.DMC100617006);
        }
        return result;
    }

    @Override
    public int unbind(Long deviceId) {

        Integer result = dmcRfidLabelOldmanService.breakDmcRfidLabelOldmanByDeviceId(deviceId);

//        DmcPointCardBind bind = dmcPointCardBindMapper.selectByPrimaryKey(deviceId);
//        if (PublicUtil.isEmpty(bind)) {
//            throw new DmcBizException(ErrorCodeEnum.DMC100617002);
//        }

        PointCardAccountQueryDto dto = new PointCardAccountQueryDto();
        dto.setDeviceIdList(Lists.newArrayList(deviceId));
        List<PointCardAccountVO> voList = omcRpcService.listPointCardAccount(dto);

        PointCardAccountVO vo = voList.get(0);

        if (vo.getTotal().compareTo(BigDecimal.ZERO) == 0 || vo.getStatus().equals(CardConstant.RETURN_HUMAN_TYPE)) {
            int i = omcRpcService.deletePointCardAccount(deviceId);
            if (i > 0) {
//                return dmcPointCardBindMapper.deleteByPrimaryKey(deviceId);
                return result;
            }
        }
        throw new DmcBizException(ErrorCodeEnum.DMC100617003);
    }

    @Override
    public int freeze(Long deviceId) {

        DmcPointCardBind bind = dmcPointCardBindMapper.selectByPrimaryKey(deviceId);

        if (bind != null && bind.getStatus().equals(CardConstant.INUSE_CARD_STATUS)) {
            bind.setStatus(CardConstant.FREEZE_HUMAN_TYPE);
        } else {
            throw new DmcBizException(ErrorCodeEnum.DMC100617004);
        }
        return dmcPointCardBindMapper.updateByPrimaryKey(bind);
    }

    @Override
    public int unfreeze(Long deviceId) {

        DmcPointCardBind bind = dmcPointCardBindMapper.selectByPrimaryKey(deviceId);

        if (bind != null && bind.getStatus().equals(CardConstant.FREEZE_HUMAN_TYPE)) {
            bind.setStatus(CardConstant.INUSE_CARD_STATUS);
        } else {
            throw new DmcBizException(ErrorCodeEnum.DMC100617005);
        }
        return dmcPointCardBindMapper.updateByPrimaryKey(bind);
    }

    @Override
    public int refund(Long deviceId) {

        DmcPointCardBind bind = dmcPointCardBindMapper.selectByPrimaryKey(deviceId);

        if (bind != null && bind.getStatus().equals(CardConstant.INUSE_CARD_STATUS)) {
            bind.setStatus(CardConstant.RETURN_HUMAN_TYPE);
            //TODO 退费

        } else {
            throw new DmcBizException(ErrorCodeEnum.DMC100617005);
        }
        return dmcPointCardBindMapper.updateByPrimaryKey(bind);
    }

    @Override
    public PageInfo<PointCardBindVO> listPage(PointCardBindQueryDto pointCardBindQueryDto) {

//        PageHelper.startPage(pointCardBindQueryDto.getPageNum(), pointCardBindQueryDto.getPageSize());
//        List<PointCardBindVO> voList = dmcPointCardBindMapper.listPage(pointCardBindQueryDto);
//
//        PointCardAccountQueryDto pointCardAccountQueryDto = new PointCardAccountQueryDto();
//        pointCardAccountQueryDto.setDeviceIdList(voList.stream().map(v -> v.getDeviceId()).collect(Collectors.toList()));
//        List<PointCardAccountVO> pointCardAccountVOS = omcRpcService.listPointCardAccount(pointCardAccountQueryDto);
//
//        if (!pointCardAccountVOS.isEmpty()) {
//            voList.forEach(a -> {
//                pointCardAccountVOS.forEach(b -> {
//                    if (a.getDeviceId().equals(b.getDeviceId())) {
//                        BeanUtils.copyProperties(b, a);
//                    }
//                });
//            });
//        }
//        return new PageInfo<>(voList);

        List<PointCardBindVO> pointCardBindVOList = Lists.newArrayList();

        RfidLabelPageQuery rfidLabelPageQuery = new RfidLabelPageQuery();
        BeanUtils.copyProperties(pointCardBindQueryDto, rfidLabelPageQuery);

        PageInfo pageInfo = dmcRfidLabelOldmanService.queryRfidLabelListWithPage(rfidLabelPageQuery);
        List<DmcRfidLabelVo> dmcRfidLabelVoList = pageInfo.getList();

        PointCardAccountQueryDto pointCardAccountQueryDto = new PointCardAccountQueryDto();
        pointCardAccountQueryDto.setDeviceIdList(dmcRfidLabelVoList.stream().map(v -> v.getId()).collect(Collectors.toList()));
        List<PointCardAccountVO> pointCardAccountVOS = omcRpcService.listPointCardAccount(pointCardAccountQueryDto);


        for (DmcRfidLabelVo dmcRfidLabelVo : dmcRfidLabelVoList) {
            if (!PubUtils.isNull(dmcRfidLabelVo.getRoleId())) {
                dmcRfidLabelVo.setBind(true);
                switch (dmcRfidLabelVo.getRoleCode()) {
                    case DeviceConstant.RFID_ROLE_CODE_OLDMAN:
                        OldmanBedRoomBuildingVo obv = (OldmanBedRoomBuildingVo) redisTemplate
                                .opsForValue().get(RedisKeyUtil.getOmcOldmanId(dmcRfidLabelVo.getOldmanId().intValue()));
                        if (PublicUtil.isNotEmpty(obv) && PublicUtil.isNotEmpty(obv.getOldmanName())) {
                            dmcRfidLabelVo.setOldmanName(obv.getOldmanName());
                        }
                        break;
                    case DeviceConstant.RFID_ROLE_CODE_EMP:
                        OpcUserVo opcUserVo = uacRpcService.queryOpcUserVoByUserId(dmcRfidLabelVo.getOldmanId());
                        if (PublicUtil.isNotEmpty(opcUserVo) && PublicUtil.isNotEmpty(opcUserVo.getUserName())) {
                            dmcRfidLabelVo.setOldmanName(opcUserVo.getUserName());
                        }
                        break;
                    case DeviceConstant.RFID_ROLE_CODE_OTHER:
                        break;
                }
            }
            PointCardBindVO vo = new PointCardBindVO();
            vo.setDeviceId(dmcRfidLabelVo.getId());
            vo.setHumanId(dmcRfidLabelVo.getOldmanId());
            vo.setName(dmcRfidLabelVo.getOldmanName());
            BeanUtils.copyProperties(dmcRfidLabelVo, vo);
            for(PointCardAccountVO accountVO : pointCardAccountVOS){
                if(accountVO.getDeviceId().equals(dmcRfidLabelVo.getId())){
                    BeanUtils.copyProperties(accountVO,vo);
                }
            }
            pointCardBindVOList.add(vo);
        }
        return new PageInfo<>(pointCardBindVOList);
    }
}
